package sg.edu.nus.iss.vmcs.customer;

import java.util.Observable;

import sg.edu.nus.iss.vmcs.exceptions.InvalidCoinException;
import sg.edu.nus.iss.vmcs.store.CashStore;
import sg.edu.nus.iss.vmcs.store.Coin;
import sg.edu.nus.iss.vmcs.store.Store;
import sg.edu.nus.iss.vmcs.store.StoreController;
import sg.edu.nus.iss.vmcs.system.MainController;
import sg.edu.nus.iss.vmcs.system.TransactionController;

public class CoinReceiver extends Observable{
	
	private MainController mCtrl;
	private TransactionController transactionController;
	private int total_inserted;
	private Coin[] coins;
	private boolean state = false;
	private StoreController storeController;
	private CashStore cstore;
	private CustomerUI customerPanel;
	
	/**
	 * 
	 * Constructor of Observable
	 * 
	 */
	public CoinReceiver(StoreController storeController, TransactionController transaction_controller){
		System.out.println("@@@@@Observer: CoinReceiver(Observable) is created");
		this.transactionController = transaction_controller;
		this.storeController=storeController;
		this.cstore=(CashStore)storeController.getStore(Store.CASH);
		this.customerPanel= transaction_controller.getCustomerPanel();
		this.coins = new Coin[15];
		this.mCtrl=transaction_controller.getMainController();
	}
	
	
	public void displayCoinInputBox() {
		
	}
	
	
	/**
	 * Method Signature not accurate. Modify according to your implementation
	 */
	
	public void startReceive(int weight){
		
	}
	
	/**
	 * Method Signature not accurate. Modify according to your implementation
	 * @param weight
	 */
	
	public void continueReceive(){
			
	}
	
	/**
	 *
	 * @param weight
	 * @throws InvalidCoinException 
	 * Author : Athirai
	 */
	
	public void receiveCoin(double weight) {
		
		//Priyanka - calling for changing the termination state
		mCtrl.setTransactionCurrentState(1);
		System.out.println("In CoinReceiver:");
		System.out.println("---------Chain Of Responsibility Coin Handling begins---------");
		try{
			Coin c = cstore.findCoin(weight);
			//customerPanel.setInvalidLabel(false);
			
			if(c!=null){
				total_inserted+=c.getValue();
				System.out.println("---------Chain Of Responsibility Coin Handling ends-----------");
				
				//Lin - setting total_inserted coin value and invalid coin state of Subject
				setValue(total_inserted, "Enter Coin");
				setState(false, "Invalid Coin");
				transactionController.processMoneyReceived(total_inserted);
			}
		}catch(InvalidCoinException e){
			System.out.println("InvalidCoinException:It is an invalid Coin");
			System.out.println("---------Chain Of Responsibility Coin Handling ends-----------");
			//Lin - setting invalid coin state of Subject
			setState(true, "Invalid Coin");
		}
	}
	
	/**
	 * Call to CoinInputBox inside CustomerUI from here.
	 * @param active
	 */
	
	public void setActive(boolean active){
		
	}
	
	/**
	 * Author : Priyanka
	 * Calling of the Store Cash use case from here 
	 * 
	 */
	
	public void storeCash(){
		
		System.out.println("Template Method : Calling CoinReceiver.Store Cash Use Case ");
		
	}
	
	/**
	 * Author : Priyanka
	 * Calling of the Refund Cash use case from here 
	 * 
	 */
	public void refundCash(){
		
		System.out.println("Template Method : Calling  CoinReceiver.Refund Cash Use Case ");
		
		//Lin - setting total_inserted coin value and invalid coin state of Subject
		setValue(total_inserted, "Refund Money");
		setState(false, "Invalid Coin");
	}

	/**
	 * Author : Lin
	 * Set method of invalid coin state which notify all its observers
	 * 
	 */
	public void setState(boolean state, String event){
		this.state = state;
		setChanged();
		notifyObservers(event);
	}
	
	public boolean getState(){
		return state;
	}
	
	/**
	 * Author : Lin
	 * Set method of total_inserted coin value which notify all its observers
	 * 
	 */
	private void setValue(int value, String event){
		this.total_inserted = value;
		setChanged();
		notifyObservers(event);
	}
	
	public void setValue(int value){
		this.total_inserted = value;
	}
	
	public int getValue(){
		return total_inserted;
	}
}